const Project = require("../models/projects");
const fse = require("fs-extra");
const path = require("path");
const shell = require("shelljs");
const archiver = require("archiver");

const packageZip = (code, url) => {
  return new Promise((resolve, reject) => {
    let output = fse.createWriteStream(
      path.join(__dirname, `../public/output/${code}.zip`)
    );
    let arch = archiver("zip", { zlib: { level: 9 } });
    arch.pipe(output);

    // 监听输出流关闭事件
    output.on("close", function () {
      console.log(arch.pointer() + " total bytes");
      console.log("压缩完成，文件大小：" + arch.pointer() + " bytes");
      resolve(false);
    });

    // 监听压缩过程中的错误
    arch.on("error", function (err) {
      resolve(false);
    });

    arch.directory(path.join(__dirname, `../../projects/${code}/dist`), false);

    arch.finalize();
    resolve(true);
  });
};

class ProjectCtl {
  async get(ctx) {
    let limit = ctx.query.limit ? ctx.query.limit : 10;
    let page = ctx.query.page ? ctx.query.page : 1;

    let where = {};
    const filters = ["code", "name", "type"];
    filters.forEach((key) => {
      if (ctx.query[key]) {
        if (key === "name" || key === "code") {
          where[key] = new RegExp(ctx.query[key]);
        } else {
          where[key] = ctx.query[key];
        }
      }
    });

    let _Project = await Project.find(where);
    limit = parseInt(limit);
    let skip = limit * (parseInt(page) - 1);
    let total = _Project.length;
    let list = [];

    if (total > 0) {
      list = await Project.find(where)
        .limit(limit)
        .skip(skip)
        .sort({ _id: -1 });
    }

    ctx.body = {
      code: 200,
      msg: "success",
      data: {
        limit: limit,
        page: page,
        list: list,
        total: total,
      },
    };
  }

  async all(ctx) {
    let _Project = await Project.find({});
    ctx.body = {
      code: 200,
      msg: "success",
      data: _Project,
    };
  }

  async create(ctx) {
    const name = ctx.request.body.name;
    const code = ctx.request.body.code;
    const apiUrl = ctx.request.body.apiUrl;
    const exit = await Project.findOne({
      $or: [{ code: code }, { name: name }],
    });
    if (exit) {
      ctx.body = {
        errCode: -1,
        msg: "项目已存在",
      };
      return;
    }
    // 同步复制文件
    const inPath = path.resolve(__dirname, "../template/simple_app");
    const outPath = path.resolve(__dirname, "../../projects/" + code);

    fse.copySync(inPath, outPath);

    const _Project = await new Project({
      name,
      code,
      apiUrl,
      createAt: new Date(),
      updateAt: new Date(),
    }).save();

    ctx.body = {
      code: 200,
      msg: "success",
      data: _Project,
    };
  }

  async info(ctx) {
    const id = ctx.query.id;
    const _Project = await Project.findOne({
      _id: id,
    });
    ctx.body = {
      code: 200,
      msg: "success",
      data: _Project,
    };
  }

  async modify(ctx) {
    const _id = ctx.request.body._id;
    const name = ctx.request.body.name;
    const code = ctx.request.body.code;
    const apiUrl = ctx.request.body.apiUrl;
    const exit = await Project.findOne({
      $or: [{ code: code }, { name: name }],
      _id: { $ne: _id },
    });
    if (exit) {
      ctx.body = {
        code: -1,
        msg: "项目已存在",
      };
      return;
    }
    const nm = await Project.findOne({ _id });
    const oldName = path.resolve(__dirname, "../../projects/" + nm.code);
    const newName = path.resolve(__dirname, "../../projects/" + code);
    console.log(oldName, newName, "===========");
    fse.renameSync(oldName, newName);
    const _Project = await Project.updateOne(
      { _id: _id },
      {
        name,
        code,
        apiUrl,
        updateAt: new Date(),
      }
    );

    ctx.body = {
      code: 200,
      msg: "success",
      data: _Project,
    };
  }

  async package(ctx) {
    const id = ctx.params.id;
    let _Project = await Project.findOne({
      _id: id,
    });
    const { name, code } = _Project;
    const dir = path.resolve(__dirname, "../../projects/" + code);
    shell.cd(dir);
    let stdout = "";
    stdout = await shell.exec("pnpm install");
    stdout = await shell.exec("npm run build");
    console.log(stdout, "=============");

    const out = packageZip(code);

    if (out) {
      ctx.body = {
        code: 200,
        msg: "success",
        data: {
          url: `/output/${code}.zip`,
        },
      };
    } else {
      ctx.body = {
        code: -1,
        msg: "打包失败",
      };
    }
  }

  async remove(ctx) {
    const id = ctx.params.id;
    let _Project = await Project.findOne({
      _id: id,
    });
    await Project.deleteOne({
      _id: id,
    });
    console.log(_Project, "dsfsdfd_Project");
    if (_Project) {
      const src = path.resolve(__dirname, "../../projects/" + _Project.code);
      if (fse.pathExistsSync(src)) {
        fse.removeSync(src);
      }

      ctx.body = {
        code: 200,
        msg: "success",
      };
    } else {
      ctx.body = {
        code: -1,
        msg: "项目不存在",
      };
    }
  }
}

module.exports = new ProjectCtl();
